﻿/* Write a method that adds two positive integer numbers represented as arrays of digits (each array element arr[i] contains a 
* digit; the last digit is kept in arr[0]). Each of the numbers that will be added could have up to 10 000 digits. */

/* STEPS TO RUN THE UNIT TEST - 1) make the class public, make the Add() method public and 
 * the return type to string, uncomment the bottom StringBuilder and return result.ToString();
 * functions (refer to the comments in the method) */
using System;
using System.Collections.Generic;
using System.Text;
namespace Digits
{
    public class AddDigits
    {
        public static void Main()
        {
            /* manually set values */
            //values (the first element/index is actually the last number!)
            //byte[] arr = { 5, 6, 5, 2, 5 };
            //byte[] arr2 = { 4, 9, 8, 9 };
            //byte[] arr = { 3, 5, 6, 4, 9, 3 };
            //byte[] arr2 = { 4, 9, 8, 9 };
            
            /* automatically set values using user input */
            string number1 = null, number2 = null;
            Console.Write("Enter number 1: ");
            number1 = Console.ReadLine();

            Console.Write("Enter number 2: ");
            number2 = Console.ReadLine();

            byte[] arr = new byte[number1.Length];
            byte[] arr2 = new byte[number2.Length];
            for (int i = 0; i < arr.Length; i++) arr[i] = (byte)(number1[i] - '0');
            Array.Reverse(arr);

            for (int i = 0; i < arr2.Length; i++) arr2[i] = (byte)(number2[i] - '0');
            Array.Reverse(arr2);

            /* unit test row */
            //string res = Add(arr, arr2);
            
            //Add() returns the summarized value in a list. Create a new list object and get it.
            List<byte> result = Add(arr, arr2);

            //Create a new StringBuilder object - we want our application to run fast. (it has to keep up with
            //arrays of up to 10 000 indexes/elements
            StringBuilder sb = new StringBuilder();
            foreach(byte var in result) sb.Append(var); //concatenate 

            //for (int i = 0; i < arr.Length; i++) Console.WriteLine(arr[i]);
            
            //output some alabala stuff
            byte[] arrclone = (byte[])arr.Clone();
            byte[] arr2clone = (byte[])arr2.Clone();
            Array.Reverse(arrclone);
            Array.Reverse(arr2clone);
            Console.WriteLine("The result of adding {0} and {1} is: {2}", string.Join("", arrclone), string.Join("", arr2clone), sb);
        }

        public static List<byte> Add(byte[] arr, byte[] arr2)
        {
            //1) clone arrays; 2) make them straight
            //int[] arr_straight_first = (int[])arr.Clone();
            //Array.Reverse(arr_straight_first);

            //int[] arr2_straight_second = (int[])arr2.Clone();
            //Array.Reverse(arr2_straight_second);

            //get array lengths
            //int arr_straight_first_nofelements = arr_straight_first.Length;
            //int arr2_straight_second_nofelements = arr2_straight_second.Length;
            int arr_nofelements = arr.Length;
            int arr2_nofelements = arr2.Length;


            /* we need to count to the smaller number, get it and assign it to count_to so we can summarize until we reach 
             * the number
            of the elements of the [smaller] array */
            byte[] smaller_composition, bigger_composition;

            if (arr_nofelements < arr2_nofelements)
            {
                smaller_composition = arr;
                bigger_composition = arr2;
            }
            else
            {
                bigger_composition = arr;
                smaller_composition = arr2;
            }

            List<byte> sum = new List<byte>(); //create new list where we will store our sum

            //count the smaller composition (array with lower length), summarize the numbers and add them to the list
            //TODO: parse cases where we have a sum > 10
            int? current_sum = null, onminder = null;
            for (int i = 0; i < smaller_composition.Length; i++)
            {
                current_sum = smaller_composition[i] + bigger_composition[i];

                //check if we have an onminder
                if (onminder != null)
                {
                    current_sum += onminder;
                    onminder = null;
                }

                if (current_sum < 10)
                    sum.Add((byte)current_sum);
                else
                {
                    //we got 1 on mind (e tva kak e na amerikanski ideq si nqmam)
                    //ex. 5+9 = 14, we got 4 and an onminder of 1

                    string onminder_strstack_ = current_sum.ToString();

                    sum.Add((byte)(onminder_strstack_[onminder_strstack_.Length - 1] - '0'));

                    onminder = onminder_strstack_[0] - '0'; //we need to substract the '0'char from our string in order
                    //to receive the integer but not the code of the integer
                    //from the code table

                    /* DEPRECATED CODE (MOVED BELOW), becase this way we have to alter the array contents
                     * this row is important! - if we have an onminder and this is the last element/index of the smaller
                     * composition, we need to add the onminder to the next relevant element/index from the bigger composition. */
                    //if (i == smaller_composition.Length-1) bigger_composition[i+1] += (byte)onminder;
                }
            }
            /* V DOLNIQ CIKYL IMA POVTARQEMOST NA KOD. SAMO CHE E 3:20 CHASA. PUSNAL 
             * SYM KYM 40 PYTI Unit Test NA PROGRAMATA, KOQTO OT VSICHKI NE VZIMASHE SAMO 1
             * ZARADI CASE-A KOGATO E .. abe vse taq spi mi se, 3 chasa e i otivam da spa, koj
             * razbral razbral */
            //add the rest
            for (int i = smaller_composition.Length; i < bigger_composition.Length; i++)
            {
                //check if we have an onminder left
                if (onminder > 0)
                {
                    byte sum_stack = (byte)(bigger_composition[i] + onminder);
                    if (sum_stack > 9)
                    {
 
                        string onminder_strstack_ = sum_stack.ToString();

                        sum.Add((byte)(onminder_strstack_[onminder_strstack_.Length - 1] - '0'));

                        onminder = onminder_strstack_[0] - '0';
                    }
                    else
                    {
                        onminder = null; //dispose of it - we do not want it getting in touch in the next iteration
                        sum.Add(sum_stack);
                    }
                }
                else
                    sum.Add(bigger_composition[i]);
            }
            if (onminder > 0) sum.Add((byte)onminder); //check if we have a left onminder

            /* THIS SECTION IS USED ONLY FOR THE UniteTest_AddDigits test project - uncomment to test */
            //StringBuilder result = new StringBuilder();
            //for (int i = sum.Count - 1; i >= 0; i--) result.Append(sum[i]);

            //return result.ToString();
            /* UNIT TEST SECTION END */

            sum.Reverse(); //reverse the array - we want a human-readable form
            return sum;

            /* DEPRECATED CODE */
            //generate a string and return it
            //for (int i = sum.Count - 1; i >= 0; i--) Console.Write(sum[i]);
        }
    }







}










